
package RepositoryHarvester;

/* import declarations */
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;



/**
 * Class to send a request and get the response from a OAI source *
 * @author Lawrence
 */
public class ServerRequest {

     /** the harvester configuration object */
    HarvestConfiguration configuration; // configuration object

    /**
     * Starts the harvest by calling its internal <code>doHarvest</code> method.
     * Also sets the harvester configuration local variables.
     * @param config the harvester configuration for the repository being harvested.
     */
    public ServerRequest(HarvestConfiguration config) throws Exception
    { // constructor that takes a HarvestConfiguration object
        configuration = config; // set the configuration object to the one passed in to constructor
        System.out.println("Starting with a request to " + configuration.getBaseURL());
        doHarvest();
    }

    /**
     * Actually performs the harvest. Sends off the request to the repository server
     * and then receives the reponse, storing it in a <code>OAIResponseHandeler</code>,
     * where it is then stored in the database.
     */
    private void doHarvest() throws Exception
    {
        
        
        String rtoken = ""; // at first there is no resumption token
        do {
            String request = generateRequest(rtoken);
            System.out.println(request);
            BufferedInputStream response = sendRequest(request);

            ResponseHandler handler = new ResponseHandler(response, configuration); // create a response handler to parse and store the response
            System.out.println("Storing the responses");
            handler.store(); // store the entries in the response in the database
            //update harvest status


            System.out.println("Getting the resumption token");
            rtoken = handler.getResumptionToken(); // get the resumption token from the response
        } while (!rtoken.equals("")); // if there is no resumption token, end the harvest

        
    }

     /**
     * Returns the http request that is to be sent to the server.
     * <p>
     * If there is a resumption token, it will use that to create the request.
     * Otherwise, it will generate a fresh request if the resumption token
     * parameter is empty.
     * @param rtoken the resumption token
     * @return the full request that is to be sent back to the Repository.
     */
    private String generateRequest(String rtoken)
    { // generate a request, adding the resumption token if necessary
        String request = "?verb=ListRecords";

        if (rtoken.equals(""))
        { // if there is no resumption token
            if (configuration.getDateFrom() != null)
            { // if there is a from date
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
                request += "&from=" + sdf.format(Timestamp.valueOf(configuration.getDateFrom()));
            }
            request += "&metadataPrefix=" + configuration.getMetadataFormat();	// set the metadata prefix
        }
        else
        {
            request += "&resumptionToken=" + rtoken;
        }

        return request;

    }

     /**
     * Sends the http request to the server, and then returns the response
     * in a <code>BufferedInputStream</code> object.
     * @param request the request to be sent to the server
     * @return the response from the server
     */
    private BufferedInputStream sendRequest(String request) throws IOException
    {
        
            URL url = new URL (configuration.getBaseURL()+request); // create URL with the base url of the server to harvest from
            URLConnection connection = url.openConnection();                                    
//            connection.setDoOutput(true); // do output is true
//
//            OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
//
//            wr.write(request);
//            wr.flush();

            connection.connect();
            BufferedInputStream response = new BufferedInputStream(connection.getInputStream()); // create a buffered stream to read from
            response.mark(2147483647); // sets the max amount of readable bytes, with the maximum amount that can be read from a stream

            return response;
       

    }



}
